package org.mx.time;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 提供系统时间服务，解决System.currentTimeMillis()在大并发情况下的低效问题
 * 
 * @author john.peng
 *
 */
public class SystemClock {
	private final Logger logger = LoggerFactory.getLogger(SystemClock.class);
	private ScheduledExecutorService scheduler = null;

	private final long precision;
	private final AtomicLong now;

	/**
	 * 构造函数，默认采用1毫秒的计时精度
	 */
	public SystemClock() {
		this(1L);
	}

	/**
	 * 构造函数
	 * @param precision 计时精度，单位毫秒
	 */
	public SystemClock(long precision) {
		super();
		this.precision = precision;
		this.now = new AtomicLong(System.currentTimeMillis());
	}

	/**
	 * 初始化线程，开始按照指定精度计时
	 */
	public void init() {
		scheduler = Executors.newSingleThreadScheduledExecutor(runnable -> {
			Thread thread = new Thread(runnable);
			thread.setDaemon(true);
			return thread;
		});
		scheduler.scheduleAtFixedRate(() -> now.set(System.currentTimeMillis()), precision, precision,
				TimeUnit.MILLISECONDS);
		if (logger.isInfoEnabled()) {
			logger.info(String.format("Initialize the SystemClock success, precision: %d ms.", precision));
		}
	}

	/**
	 * 释放线程资源
	 */
	public void close() {
		if (scheduler != null) {
			scheduler.shutdown();
			scheduler = null;
			if (logger.isInfoEnabled()) {
				logger.info("Close the SystemClock thread success.");
			}
		}
	}

	/**
	 * 获取当前时间，单位毫秒
	 * @return 当前时间
	 */
	public long now() {
		return now.get();
	}
}
